#ifndef BASEMODEL_AUDIO_H
#define BASEMODEL_AUDIO_H

#include "common.h"

// 确保结构体按字节对齐，避免编译器填充
#pragma pack(push, 1)

// 音频帧相关常量
#define WEBSOCKET_PROTOCOL_VERSION 2
#define UDP_PROTOCOL_VERSION 3
#define AUDIO_TYPE_OPUS 0
#define WEBSOCKET_HEADER_SIZE 16    // 2+2+4+4+4 = 16字节
#define UDP_NONCE_SIZE 16           // AES nonce大小
#define DEFAULT_SAMPLE_RATE 16000
#define DEFAULT_CHANNELS 1
#define DEFAULT_FRAME_DURATION_MS 60

// 最大音频载荷大小
#define MAX_AUDIO_PAYLOAD_SIZE 8192

// WebSocket音频帧（协议版本2）
// 帧格式：|version u16|type u16|reserved u32|timestamp u32|payload_size u32|payload [u8]|
typedef struct {
    uint16_t version;       // 协议版本，WebSocket固定为2
    uint16_t type;          // 音频类型，0表示opus编码
    uint32_t reserved;      // 保留字段，固定为0
    uint32_t timestamp;     // 时间戳（仅在启用服务器端AEC时使用，否则为0）
                           // SERVER-AEC使用Timestamp的逻辑是每次发送音频包且同时接收tts时传入经过的时间(ms)，不需要aec时传0
    uint32_t payload_size;  // 音频数据大小
    uint8_t payload[MAX_AUDIO_PAYLOAD_SIZE]; // 音频数据（opus编码）
} websocket_audio_frame_t;

// UDP音频帧头部（协议版本3，加密前）
// 帧格式：|type u8|flags u8|payload_len u16|ssrc u32|timestamp u32|sequence u32|
typedef struct {
    uint8_t type;           // 音频类型，0表示opus编码
    uint8_t flags;          // 标志位，保留字段
    uint16_t payload_len;   // 音频数据长度
    uint32_t ssrc;          // 同步源标识符（保留）
    uint32_t timestamp;     // 时间戳（仅在启用服务器端AEC时使用，否则为0）
                           // SERVER-AEC使用Timestamp的逻辑是每次发送音频包且同时接收tts时传入经过的时间(ms)，不需要aec时传0
    uint32_t sequence;      // 序列号，用于数据包排序和去重
} udp_audio_frame_header_t;

// UDP加密配置
typedef struct {
    uint8_t key[16];        // AES密钥（16字节）
    uint8_t nonce[16];      // 初始nonce（16字节）
} udp_encryption_config_t;

// UDP加密音频帧（协议版本3）
// 加密后格式：|modified_nonce[16]|encrypted_payload[...]|
typedef struct {
    udp_encryption_config_t encryption_config; // 加密配置
    uint32_t sequence;      // 当前序列号
    uint32_t opus_data_size; // 原始opus数据大小
    uint8_t opus_data[MAX_AUDIO_PAYLOAD_SIZE]; // 原始opus数据
} udp_encrypted_audio_frame_t;

// 加密后的完整数据包结构
typedef struct {
    uint8_t modified_nonce[16];  // 修改后的nonce（16字节）
    uint8_t encrypted_payload[MAX_AUDIO_PAYLOAD_SIZE]; // 加密的音频数据
    uint32_t encrypted_size;     // 实际加密数据的大小
} udp_encrypted_packet_t;

// 恢复原来的字节对齐
#pragma pack(pop)

// 音频帧操作函数声明

/**
 * 创建WebSocket音频帧
 * @param frame 输出的音频帧结构体
 * @param opus_data opus编码的音频数据
 * @param data_size 音频数据大小
 * @param timestamp 时间戳（AEC使用，否则为0）
 */
void create_websocket_audio_frame(
    websocket_audio_frame_t* frame,
    const uint8_t* opus_data,
    uint32_t data_size,
    uint32_t timestamp
);

/**
 * 将WebSocket音频帧序列化为字节流（网络字节序）
 * @param frame 音频帧结构体
 * @param buffer 输出缓冲区
 * @param buffer_size 缓冲区大小
 * @return 实际写入的字节数，失败返回0
 */
uint32_t serialize_websocket_audio_frame(
    const websocket_audio_frame_t* frame,
    uint8_t* buffer,
    uint32_t buffer_size
);

/**
 * 从字节流反序列化WebSocket音频帧
 * @param buffer 输入字节流
 * @param buffer_size 缓冲区大小
 * @param frame 输出的音频帧结构体
 * @return 解析成功返回true，失败返回false
 */
bool deserialize_websocket_audio_frame(
    const uint8_t* buffer,
    uint32_t buffer_size,
    websocket_audio_frame_t* frame
);

/**
 * 创建UDP音频帧头部
 * @param header 输出的头部结构体
 * @param payload_len 音频数据长度
 * @param sequence 序列号
 * @param timestamp 时间戳（AEC使用，否则为0）
 */
void create_udp_audio_frame_header(
    udp_audio_frame_header_t* header,
    uint16_t payload_len,
    uint32_t sequence,
    uint32_t timestamp
);

/**
 * 准备UDP加密音频帧
 * @param frame 输出的加密音频帧结构体
 * @param opus_data opus编码的音频数据
 * @param data_size 音频数据大小
 * @param sequence 序列号
 * @param config 加密配置
 */
void prepare_udp_encrypted_frame(
    udp_encrypted_audio_frame_t* frame,
    const uint8_t* opus_data,
    uint32_t data_size,
    uint32_t sequence,
    const udp_encryption_config_t* config
);

/**
 * 修改nonce用于AES-CTR加密
 * 按照协议规范修改nonce中的特定字段
 * @param modified_nonce 输出的修改后nonce
 * @param original_nonce 原始nonce
 * @param payload_size 载荷大小
 * @param timestamp 时间戳
 * @param sequence 序列号
 */
void modify_nonce_for_encryption(
    uint8_t modified_nonce[16],
    const uint8_t original_nonce[16],
    uint16_t payload_size,
    uint32_t timestamp,
    uint32_t sequence
);

/**
 * 从十六进制字符串创建加密配置
 * @param config 输出的加密配置
 * @param key_hex 十六进制格式的密钥字符串（32个字符）
 * @param nonce_hex 十六进制格式的nonce字符串（32个字符）
 * @return 解析成功返回true，失败返回false
 */
bool create_encryption_config_from_hex(
    udp_encryption_config_t* config,
    const char* key_hex,
    const char* nonce_hex
);

/**
 * 获取WebSocket音频帧的总大小
 * @param frame 音频帧结构体
 * @return 序列化后的总字节数
 */
static inline uint32_t get_websocket_frame_total_size(const websocket_audio_frame_t* frame) {
    return WEBSOCKET_HEADER_SIZE + frame->payload_size;
}

/**
 * 验证WebSocket音频帧的有效性
 * @param frame 音频帧结构体
 * @return 有效返回true，无效返回false
 */
static inline bool validate_websocket_audio_frame(const websocket_audio_frame_t* frame) {
    return frame->version == WEBSOCKET_PROTOCOL_VERSION &&
           frame->type == AUDIO_TYPE_OPUS &&
           frame->payload_size <= MAX_AUDIO_PAYLOAD_SIZE;
}

/**
 * 验证UDP音频帧头部的有效性
 * @param header 头部结构体
 * @return 有效返回true，无效返回false
 */
static inline bool validate_udp_audio_header(const udp_audio_frame_header_t* header) {
    return header->type == AUDIO_TYPE_OPUS &&
           header->payload_len <= MAX_AUDIO_PAYLOAD_SIZE;
}

#endif // BASEMODEL_AUDIO_H
